package ouyuwang.gpsbox;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.AudioManager;
import android.media.SoundPool;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.youtoo.drive.Behavior;
import com.youtoo.drive.GPSEvent;
import com.youtoo.drive.Recognizer;
import com.youtoo.drive.WindowData;
import com.youtoo.drive.YTSettings;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * Created by yupeng on 17/07/26.
 */

public class Main extends Activity implements View.OnClickListener {

    private static final int windowLength = 5;
    private static final double upThreshold = 6;
    private static final double downThreshold = -7;

    private boolean isStarted = false;

    private TextView resultContent;
    private TextView speedText;
    private TextView behaviorTitle;
    private Button control;
    private String bestProvider;
    private TextView message = null;
    private int offset;
    private int badBehaviorTimes = 0;

    private FileUtil fileUtil;

    private YTSettings ytSettings;
    private Recognizer recognizer;
    private SoundPool soundPool;
    private int tipSoundID;

    private LocationManager locationManager;
    private LocationListener locationListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        resultContent = (TextView) findViewById(R.id.logView);
        speedText = (TextView) findViewById(R.id.speedText);
        behaviorTitle = (TextView) findViewById(R.id.behaviorTitle);
        resultContent.setMovementMethod(ScrollingMovementMethod.getInstance());
        control = (Button) findViewById(R.id.controlBtn);
        control.setOnClickListener(this);
        message = (TextView) findViewById(R.id.message);

        behaviorTitle.setText("不良驾驶行为 " + badBehaviorTimes + " 次:");
        permissionCheck();

        soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 5);
        tipSoundID = soundPool.load(this, R.raw.tips, 0);

    }

    public void permissionCheck() {
        String[] needPermissions = {
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.ACCESS_FINE_LOCATION
        };
        checkPermissions(needPermissions);
    }

    /**
     * @param
     * @since 2.5.0
     * requestPermissions方法是请求某一权限，
     */
    private void checkPermissions(String... permissions) {
        List<String> needRequestPermissonList = findDeniedPermissions(permissions);
        if (null != needRequestPermissonList
                && needRequestPermissonList.size() > 0) {
            ActivityCompat.requestPermissions(this,
                    needRequestPermissonList.toArray(
                            new String[needRequestPermissonList.size()]),
                    0);
        }
    }

    /**
     * 获取权限集中需要申请权限的列表
     *
     * @param permissions
     * @return
     * @since 2.5.0
     * checkSelfPermission方法是在用来判断是否app已经获取到某一个权限
     * shouldShowRequestPermissionRationale方法用来判断是否
     * 显示申请权限对话框，如果同意了或者不在询问则返回false
     */
    private List<String> findDeniedPermissions(String[] permissions) {
        List<String> needRequestPermissonList = new ArrayList<String>();
        for (String perm : permissions) {
            if (ContextCompat.checkSelfPermission(this,
                    perm) != PackageManager.PERMISSION_GRANTED) {
                needRequestPermissonList.add(perm);
            } else {
                if (ActivityCompat.shouldShowRequestPermissionRationale(
                        this, perm)) {
                    needRequestPermissonList.add(perm);
                }
            }
        }
        return needRequestPermissonList;
    }

    @Override
    public void onClick(View v) {
        String eventMessage = "已启动，开始行为识别...";
        FileUtil.clearEmptyFiles();//清除空白文件
        if (isStarted) {//已经是启动状态，再点击就触发停止事件
            fileUtil.close();
            locationManager.removeUpdates(locationListener);
            badBehaviorTimes = 0;
            isStarted = false;
            control.setBackgroundColor(getResources().getColor(R.color.colorGreen));
            control.setText("出发!");
            eventMessage = "已停止识别";
        } else {
            isStarted = true;
            control.setBackgroundColor(getResources().getColor(R.color.colorAccent));
            control.setText("停止!");
            fileUtil = FileUtil.init(TimeUtil.nowTimeFileName());
            ytSettings = YTSettings.build().setWindowLength(windowLength).setUpThreshold
                    (upThreshold).setDownThreshold(downThreshold);
            recognizer = Recognizer.build(ytSettings);

            locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

            //GPS是否开启检查
            if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                Toast.makeText(this, "请开启GPS导航...", Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivityForResult(intent, 0);
                return;
            }
            locationListener = new LocationHandler(this);
            bestProvider = locationManager.getBestProvider(getCriteria(), true);
            locationManager.addGpsStatusListener(new GPStatusHandler(this));
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0,
                    locationListener);
        }
        updateMessage(eventMessage);
    }

    private Criteria getCriteria() {
        Criteria criteria = new Criteria();
        // 设置定位精确度 Criteria.ACCURACY_COARSE比较粗略，Criteria.ACCURACY_FINE则比较精细
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        // 设置是否要求速度
        criteria.setSpeedRequired(false);
        // 设置是否允许运营商收费
        criteria.setCostAllowed(false);
        // 设置是否需要方位信息
        criteria.setBearingRequired(false);
        // 设置是否需要海拔信息
        criteria.setAltitudeRequired(false);
        // 设置对电源的需求
        criteria.setPowerRequirement(Criteria.POWER_LOW);
        return criteria;
    }

    public LocationManager getLocationManager() {
        return locationManager;
    }

    private LinkedList<String> messages = new LinkedList<>();

    public void updateMessage(String info) {
        if (messages.size() == 3) {
            messages.removeFirst();
        }
        messages.addLast(info);
        message.setText("");
        for (String msg : messages) {
            message.append(msg + "\n");
        }
    }

    public void updateLocation(Location location) {
        if (location != null) {
            double longitude = location.getLongitude();
            double latitude = location.getLatitude();
            double speed = location.getSpeed();
            DecimalFormat df = new DecimalFormat("#.0");
            speedText.setText(df.format(speed * 3.6) + "");
            if (recognizer != null) {
                Behavior behavior = recognizer.recognition(new Date().getTime(), longitude, latitude,
                        speed);
                updateBehavior(behavior);
            }


        }
    }

    public void updateBehavior(Behavior behavior) {
        SimpleDateFormat sf = new SimpleDateFormat("HH:mm:ss");
        if (!behavior.getMode().equals(Behavior.Mode.NORMAL)) {
            badBehaviorTimes++;
            behaviorTitle.setText("不良驾驶行为 " + badBehaviorTimes + " 次:");
            soundPool.play(tipSoundID, 1, 1, 0, 0, 1);
            resultContent.append(sf.format(new Date(behavior.getEndEvent().getTime())) + "     :     "
                    + behavior.getMode().getName() + "\n");
            offset = resultContent.getLineCount() * resultContent.getLineHeight();
            if (offset > resultContent.getHeight()) {
                resultContent.scrollTo(0, offset - resultContent.getHeight());
            }

            if (fileUtil != null) {//如果识别出非正常驾驶行为则记录该窗口
                WindowData data = WindowData.init(ytSettings);
                for (GPSEvent gpsEvent : data) {
                    fileUtil.write(gpsEvent.getTime() + "," + gpsEvent.getLongitude() + "," +
                            gpsEvent.getLatitude() +
                            "," +
                            gpsEvent.getSpeed() + "," + gpsEvent.getDistanceToPreviousLocation());
                }
            }
        }
    }

}
